<script lang="ts" setup>
import { Form, Input, Select, TabPane, Tooltip, Button, Drawer, Textarea, message, Switch, InputNumber, Row, Col } from 'ant-design-vue'
import {
    type IBeforeCaseStep,
    type IBeforeConstantSelectOptions,
} from '../../types/apis/before-case'
import {
    type IDatabaseStepAssertion,
    type IDatabaseConstantSelectOptions,
    defaultWithIDatabaseStepAssertion
} from '../../types/apis/database_msg'


import type RequestConfigVue from './RequestConfig.vue'
import type { ComponentExposed } from 'vue-component-type-helpers'
import { ref, watch, nextTick } from 'vue';
import type { AfterFetchContext } from '@vueuse/core'
import type { IBasic } from '../../types/apis/basic'
import { objectSerializer, objectDeserializer } from '../../utils/internal'
import type { ColumnsType } from 'ant-design-vue/es/table'
import type { IDatabase } from '../../types/apis/database_msg';
import { useCustomFetch } from '../../composables/custom-fetch'


defineProps<{
    databaseConstantSelectOptions: IDatabaseConstantSelectOptions,
    beforeConstantSelectOptions: IBeforeConstantSelectOptions
}>()
const selectedStep = defineModel<IBeforeCaseStep>('selectedStep', {
    required: true,
})

const requestConfigRef = ref<ComponentExposed<typeof RequestConfigVue>>()

const globalConfig = useGlobalConfigStore()

const columnsWithAssertion: ColumnsType<any> = [
    { title: '断言方式', dataIndex: 'mode', key: 'mode' },
    { title: '断言动作', dataIndex: 'action', key: 'action' },
    { title: '字段名', dataIndex: 'field', key: 'field' },
    { title: '预期值', dataIndex: 'value', key: 'value' },
    { title: '操作', dataIndex: 'operator', key: 'operator', width: 200 },
]
const dataSourceWithAssertion = ref<IDatabaseStepAssertion[]>([])

async function deserialize() {
    await nextTick()
    dataSourceWithAssertion.value = objectDeserializer(
        selectedStep.value.assertion,
        true,
    )

}

function serialize() {
    selectedStep.value.assertion = objectSerializer(dataSourceWithAssertion.value)

}

watch(
    selectedStep,
    async () => {
        await deserialize()
    },
    { deep: true, immediate: true },
)
defineExpose({ serialize })

const databaseId = ref()

const { isFetching: loadingWithGetDatabases, data: databaseMsgs } =
    useCustomFetch<IDatabase[]>(`/engine-service/api/v1/database/list`, {
        afterFetch(ctx: AfterFetchContext<IBasic<IDatabase[]>>) {
            if (ctx.data && ctx.data.code === 0) {
                if (databaseId.value === -1) {
                    databaseId.value = ctx.data.data[0].id
                }
                return {
                    data: ctx.data.data,
                    response: ctx.response,
                }
            }
            return {
                data: [],
                response: ctx.response,
            }
        },
    })


/**
 * 重试开关变动
 */
let isRetrySwitchType = ref(!globalConfig.selectedStep.isRetry);
watch(() => globalConfig.selectedStep.isRetry,
    (newValue) => {
        if (newValue) {
            isRetrySwitchType.value = false
        } else {
            isRetrySwitchType.value = true
        }
    },
    { deep: true }
)
</script>


<template>
    <!-- 主体部分 -->
    <div my-6>

        <Form :model="selectedStep">
            <Row :gutter="27">
                <Col :span="12">
                <Form.Item label="用例名称">
                    <Input v-model:value="selectedStep.name" placeholder="请输入用例名称" />
                </Form.Item>
                </Col>
                <Col :span="12">
                <Form.Item label="数据库配置">
                    <Select v-model:value="selectedStep.databaseId" :loading="loadingWithGetDatabases">
                        <Select.Option v-for="{ id, description } in databaseMsgs" :key="id" :value="id">
                            <Tooltip :title="description">{{ description }}</Tooltip>
                        </Select.Option>
                    </Select>
                    <!-- <Input v-model:value="selectedStep.databaseId" placeholder="请选择数据库配置" /> -->
                </Form.Item>
                </Col>
            </Row>

            <Form.Item label="SQL文本">
                <Textarea style="height: 300px; width: 100%" v-model:value="selectedStep.sqlText" placeholder="请输入SQL文本" />
            </Form.Item>

            <Row :gutter="30">
                <Col :span="12">
                <Form.Item label="重试类型">
                    <Select v-model:value="selectedStep.retryType" :disabled="true" style="width: 100%;">
                        <Select.Option value="同步">同步重试</Select.Option>
                        <Select.Option value="异步">异步重试</Select.Option>
                    </Select>
                </Form.Item>
                </Col>
                <Col :span="12">
                <Form.Item label="首次重试间隔(单位: 秒 )">
                    <InputNumber v-model:value="selectedStep.retryFirstInterval" :disabled="isRetrySwitchType"
                        style="width: 100%;" />
                </Form.Item>

                </Col>
            </Row>
            <Row :gutter="30">
                <Col :span="12">
                <Form.Item label="重试次数">
                    <InputNumber v-model:value="selectedStep.retryCount" :disabled="isRetrySwitchType"
                        style="width: 100%;" />
                </Form.Item>

                </Col>
                <Col :span="12">
                <Form.Item label="失败是否重试(默认关闭)">
                    <Switch v-model:checked="selectedStep.isRetry" />
                </Form.Item>
                </Col>
            </Row>
        </Form>

        <RequestConfig ref="requestConfigRef" v-model:body-type="selectedStep.bodyType">
            <template #foot>
                <TabPane key="assertion" tab="断言">
                    <EditableTable v-model:data-source-proxy="dataSourceWithAssertion" :custom-fields="['mode', 'action']"
                        :columns="columnsWithAssertion" @add-data="
                            dataSourceWithAssertion.push({
                                ...defaultWithIDatabaseStepAssertion,
                            })
                            ">
                        <template #bodyCell="{ column, isEdit, currentEditableInstance }">
                            <template v-if="isEdit && column.key === 'mode'">
                                <Select v-model:value="currentEditableInstance[column.key!]">
                                    <Select.Option v-for="item in databaseConstantSelectOptions.db_assert_mode"
                                        :key="item.id" :value="item.value">
                                        <Tooltip :title="item.remark">
                                            {{ item.name }}
                                        </Tooltip>
                                    </Select.Option>
                                </Select>
                            </template>

                            <template v-if="isEdit && column.key === 'action'">
                                <Select v-model:value="currentEditableInstance[column.key!]">
                                    <Select.Option v-for="item in databaseConstantSelectOptions.db_assert_action"
                                        :key="item.id" :value="item.value">
                                        <Tooltip :title="item.remark">
                                            {{ item.name }}
                                        </Tooltip>
                                    </Select.Option>
                                </Select>
                            </template>
                        </template>
                    </EditableTable>
                </TabPane>
            </template>
        </RequestConfig>
    </div>
</template>
